import marimo

__generated_with = "0.15.3"
app = marimo.App(width="medium")


@app.cell
def __():
    import marimo as mo
    return mo,


@app.cell
def __(mo):
    mo.md(
        r"""
        # 理解机器学习中的潜在空间

        ## 学习深度学习的一个基础但经常"隐藏"的概念

        ![预览图片](https://miro.medium.com/v2/resize:fit:700/1*R7A0qNVuOjgGh6pj4WUq5A.png)

        **作者：** [Ekin Tiu](https://medium.com/@ekintiu)  
        **背景：** 斯坦福大学计算机科学 | 斯坦福机器学习小组  
        **发布平台：** [Towards Data Science](https://medium.com/towards-data-science)  
        **发布时间：** 2020年2月4日（更新：2023年6月20日）  
        **阅读时间：** 约9分钟

        ---

        ### 什么是潜在空间？

        > 如果我必须用一句话来描述潜在空间，它简单地意味着压缩数据的表示。

        想象一个手写数字（0-9）的大型数据集，如上图所示。同一数字的手写图像（即3的图像）彼此之间最相似，相比于不同数字的其他图像（即3与7）。但我们能训练算法识别这些相似性吗？*如何做到？*

        如果你训练了一个模型来*分类数字*，那么你*也*训练了模型学习图像之间的"结构相似性"。实际上，这就是模型能够首先分类数字的方式——通过学习每个数字的特征。

        如果这个过程对你来说似乎是"隐藏的"，那是因为它确实是隐藏的。潜在（Latent），按定义，意味着"隐藏的"。

        "潜在空间"的概念*很重要*，因为它的实用性是"深度学习"的核心——*学习数据特征并简化数据表示以寻找模式*。

        感兴趣吗？让我们逐步分解潜在空间：
        """
    )
    return


@app.cell
def __(mo):
    mo.md(
        r"""
        ### 为什么在机器学习中压缩数据？

        **数据压缩**被定义为使用比原始表示更少的位来编码信息的过程。这就像取一个19维数据点（需要19个值来定义唯一点）并将所有信息压缩到9维数据点中。

        ![压缩示意图](https://miro.medium.com/v2/resize:fit:700/0*zG3k_ciZomNRaO-K.jpg)

        **压缩示意图** — 来源：Faust 2013

        在机器学习中，数据压缩通常是为了*学习关于数据点的重要信息*。让我用一个例子来解释。

        假设我们想要训练一个模型使用全卷积神经网络（FCN）对图像进行分类（即给定数字图像输出数字编号）。当模型"学习"时，它只是在每一层学习*特征*（边缘、角度等），并将特征组合归因于特定输出。

        但每次模型通过数据点学习时，图像的*维度*首先被*减少*，然后最终增加（见下面的编码器和瓶颈）。当维度减少时，我们认为这是一种有损压缩的形式。

        ![卷积神经网络描述](https://miro.medium.com/v2/resize:fit:700/0*kHJ_LsPi-jz_CreZ.png)

        **卷积神经网络描述** — 来源：Hackernoon潜在空间可视化

        因为模型需要*重建*压缩数据（见解码器），它必须学会存储*所有相关信息*并忽略噪声。这就是压缩的价值——它允许我们摆脱任何无关信息，只专注于最重要的特征。

        **这种"压缩状态"就是我们数据的潜在空间表示。**

        ### 我所说的"空间"是什么意思？

        你可能想知道为什么我们称它为潜在*空间*。毕竟，压缩数据，乍一看，可能不会唤起任何"空间"的感觉。

        但这里有一个类比。

        在这个相当简单的例子中，假设我们的原始数据集是维度为5 x 5 x 1的图像。我们将潜在空间维度设置为3 x 1，意味着我们的压缩数据点是一个3维向量。

        ![5x5x1数据示例](https://miro.medium.com/v2/resize:fit:700/0*rZn-ksyRTUpDUxh7)

        **5x5x1数据示例**

        ![潜在空间中的3x1压缩数据示例](https://miro.medium.com/v2/resize:fit:700/0*GRY4C_Ov5RYMn6Vi)

        **"潜在空间"中的3x1压缩数据示例**

        现在，每个压缩数据点仅由3个数字唯一定义。这意味着我们可以在3D平面上绘制这些数据（一个数字是x，另一个是y，另一个是z）。

        ![3D空间中的点](https://miro.medium.com/v2/resize:fit:700/1*djUvYgePXdjMbdbGsDq2eg.png)

        **点(0.4, 0.3, 0.8)在3D空间中的图形**

        这就是我们所指的"空间"。

        > 每当我们在潜在空间中绘制点或思考点时，我们可以将它们想象为空间中的坐标，其中**"相似"的点**在图形上**更接近**。

        一个自然出现的问题是，我们如何想象4D点或n维点的空间，甚至非向量（因为潜在空间表示不需要是2维或3维向量，通常也不是，因为会丢失太多信息）。

        不令人满意的答案是，*我们不能*。我们是3维生物，无法理解n维空间（其中n > 3）。然而，有一些工具如t-SNE可以将我们的高维潜在空间表示转换为我们*可以*可视化的表示（2D或3D）。（见下面的**可视化潜在空间**部分。）

        但你可能想知道，什么*是*"相似"的图像，为什么减少数据的维度会使相似的图像在空间中"更接近"？
        """
    )
    return


@app.cell
def __(mo):
    mo.md(
        r"""
        ### 我所说的"相似"是什么意思？

        如果我们看三张图像，两张椅子和一张桌子，我们很容易说两张椅子图像最*相似*，而桌子与任一椅子图像最不同。

        ![椅子图像1](https://miro.medium.com/v2/resize:fit:700/0*BUSdEVlaSwZoYeGt.jpg)
        ![椅子图像2](https://miro.medium.com/v2/resize:fit:700/0*XajTWbn1wZFtQ3ZT.JPG)
        ![桌子图像](https://miro.medium.com/v2/resize:fit:700/0*xifBa5mzuIpQglvm.JPG)

        但是什么使这两张椅子图像"更相似"？椅子有*可区分的特征*（即靠背、无抽屉、腿之间的连接）。这些都可以通过学习边缘、角度等模式被我们的模型"理解"。

        如前所述，这些特征被打包在数据的潜在空间表示中。

        因此，当维度减少时，每个图像独有的"无关"信息（即椅子颜色）从我们的潜在空间表示中"移除"，因为只有每个图像最*重要*的特征存储在潜在空间表示中。

        结果，当我们减少维度时，两张椅子的表示变得不那么独特，更加相似。如果我们在空间中想象它们，它们会"更接近"。

        *请注意，我在整篇文章中提到的"接近度"度量是一个模糊的术语，*不是*确定的欧几里得距离，因为空间中有多种距离定义。

        ### 为什么潜在空间很重要？

        潜在空间概念确实很有趣。但*如何*使用它？*何时*使用它？最重要的是，*为什么*？

        我们会发现潜在空间"隐藏"在我们许多喜爱的图像处理网络、生成模型等中。

        虽然潜在空间对大多数人来说是隐藏的，但*确实*有某些任务，理解潜在空间不仅有帮助，而且是必要的。

        #### 表示学习

        我们数据的潜在空间表示包含表示原始数据点所需的所有重要信息。

        这种表示*必须*然后表示原始数据的**特征**。

        换句话说，模型*学习*数据特征并简化其表示以使其更容易分析。

        这是一个称为**表示学习**概念的核心，定义为一组技术，允许系统从*原始数据*中发现*特征检测*或*分类*所需的*表示*。

        在这个用例中，我们的**潜在空间表示**用于将更复杂的原始数据形式（即图像、视频）转换为"更方便处理"和分析的更简单表示。

        下面列出了表示学习的具体实例。

        #### 流形

        潜在空间是**流形学习**中的一个基本概念，这是表示学习的一个子领域。

        数据科学中的**流形**可以理解为以某种方式"相似"的数据组或子集。

        *这些相似性，通常在高维空间中不可感知或模糊，一旦我们的数据在潜在空间中表示，就可以被发现。*

        以下面的"瑞士卷"为例。

        ![瑞士卷3D](https://miro.medium.com/v2/resize:fit:700/0*Emrh5MYcuMD0ADwB.png)
        ![瑞士卷2D](https://miro.medium.com/v2/resize:fit:700/0*4VJXQFucdJcMYoo9.png)

        在3D中，我们知道*确实*存在相似数据点的组，但用高维数据描绘这样的组要困难得多。

        > 通过将我们数据的维度减少到2D，在这种情况下可以被认为是"潜在空间"表示，我们能够更容易地区分数据集中的流形（相似数据组）。

        要了解更多关于流形和流形学习的信息，我推荐以下文章：

        🔗 [数据科学中的流形——简要概述](https://towardsdatascience.com/manifolds-in-data-science-a-brief-overview-2e9dde9437e5)

        🔗 [流形学习 — scikit-learn文档](https://scikit-learn.org/stable/modules/manifold.html)
        """
    )
    return


@app.cell
def __(mo):
    mo.md(
        r"""
        #### 自编码器和生成模型

        一种常见的深度学习模型类型，它操纵潜在空间中数据的"接近度"，是**自编码器**——一个充当恒等函数的神经网络。换句话说，自编码器学习输出任何输入的内容。

        ![自编码器的一般架构](https://miro.medium.com/v2/resize:fit:700/0*dknVUIxkjQ3ZV8y0.png)

        **自编码器的一般架构**

        现在，如果你是该领域的新手，你可能想知道，我们为什么需要一个做这件事的模型？如果它输出的只是自己，似乎相当无用...

        虽然这种推理是有效的，但我们不太关心模型*输出*什么。我们更关心模型在过程中*学习*什么。

        当我们强制模型成为恒等函数时，我们强制它将所有数据的相关特征存储在压缩表示中，以便在该压缩形式中有足够的信息，使模型能够"准确地"重建它。*听起来熟悉吗？*应该的，因为这种压缩表示就是我们的潜在空间表示（上图中的红色块）。

        我们已经看到了如何在潜在空间中更容易发现模式，因为相似的数据点会倾向于聚集在一起，但我们还没有看到如何从这个潜在空间中采样点来看似生成"新"数据。

        ![通过潜在空间插值生成图像](https://miro.medium.com/v2/resize:fit:700/0*6Nrb168aK7xoaV8b.png)

        **通过潜在空间插值生成图像** — 来源：*随机噪声向量在潜在空间上的双线性插值*，图20

        在上面的例子中，我们可以通过*在潜在空间上插值*生成不同的面部结构，并使用我们的模型解码器将潜在空间表示重建为与原始输入相同维度的2D图像。

        ### 我所说的在潜在空间上插值是什么意思？

        假设我已经将前一节中的椅子图像压缩为以下2D向量，[0.4, 0.5]和[0.45, 0.45]。假设桌子被压缩为[0.6, 0.75]。如果我要在潜在空间上插值，我会在"椅子"聚类和"桌子"聚类*之间*的潜在空间中采样点。

        我们可以将这些采样的2D向量输入模型的解码器，瞧！我们得到看起来像椅子和桌子之间变形的"新"图像。*新加了引号，因为这些生成的图像在技术上不独立于原始数据样本。

        下面是两种椅子类型在潜在空间中线性插值的例子。

        ![潜在空间中的插值](https://miro.medium.com/v2/resize:fit:700/0*cYaaF2pFLECohCaI.gif)

        **潜在空间中的插值** — 来源：Hackernoon潜在空间可视化

        图像生成仍然是一个活跃的研究领域，潜在空间是一个必须理解的基本概念。请参阅以下文章了解生成模型的更多用例，以及使用GAN（生成对抗网络）进行潜在空间插值的实际例子，这是另一个使用潜在空间表示的生成模型。

        🔗 [生成对抗网络（GAN）的18个令人印象深刻的应用](https://machinelearningmastery.com/impressive-applications-of-generative-adversarial-networks/)

        🔗 [如何在生成面部时探索GAN潜在空间](https://machinelearningmastery.com/how-to-interpolate-and-perform-vector-arithmetic-with-faces-using-a-generative-adversarial-network/)

        ### 可视化潜在空间

        有关潜在空间可视化的更多信息，我推荐Hackernoon的文章，该文章提供了使用t-SNE算法在2D空间中可视化数字图像之间相似性的实际例子。

        🔗 [潜在空间可视化——深度学习要点#2](https://hackernoon.com/latent-space-visualization-deep-learning-bits-2-bd09a46920df)

        **特色：** 插值、t-SNE投影（附gif和示例！）
        """
    )
    return


@app.cell
def __(mo):
    mo.md(
        r"""
        ### 关键要点

        - **潜在空间**简单地说是压缩数据的表示，其中相似的数据点在空间中更接近。
        - 潜在空间对于学习数据特征和为分析寻找更简单的数据表示很有用。
        - 我们可以通过在潜在空间中分析数据来理解数据点之间的模式或结构相似性，无论是通过流形、聚类等。
        - 我们可以在潜在空间中插值数据，并使用我们模型的解码器来"生成"数据样本。
        - 我们可以使用t-SNE和LLE等算法可视化潜在空间，这些算法将我们的潜在空间表示转换为2D或3D。

        ### 实用应用总结

        #### 🧠 **核心概念**
        - **定义**：压缩数据的表示空间
        - **特性**：相似数据点在空间中更接近
        - **目的**：学习重要特征，忽略噪声

        #### 🔧 **主要应用**
        - **表示学习**：简化复杂数据的表示
        - **流形学习**：发现数据中的隐藏结构
        - **自编码器**：数据压缩和重建
        - **生成模型**：创建新的数据样本
        - **数据可视化**：高维数据的低维表示

        #### 📊 **技术工具**
        - **t-SNE**：高维数据可视化
        - **自编码器**：学习潜在表示
        - **GAN**：生成新数据
        - **流形学习算法**：发现数据结构

        #### 🎯 **实际价值**
        - **特征提取**：自动学习重要特征
        - **数据压缩**：减少存储和计算需求
        - **模式识别**：发现数据中的隐藏模式
        - **数据生成**：创建新的合成数据
        - **异常检测**：识别不寻常的数据点

        ### 结语

        在学习潜在空间时，我被这个"隐藏"但基本的概念所吸引。我希望这篇文章揭开了潜在空间表示的神秘面纱，并提供了我作为新手渴望的深度学习的"更深理解"。

        潜在空间是现代机器学习和深度学习的核心概念之一。理解它不仅有助于更好地理解现有模型的工作原理，还为开发新的算法和应用提供了基础。

        ---

        **原文链接：** [Understanding Latent Space in Machine Learning](https://towardsdatascience.com/understanding-latent-space-in-machine-learning-de5a7c687d8d)

        **推荐阅读：**
        - 流形学习相关文章
        - 自编码器和生成模型教程
        - t-SNE和其他降维技术
        - GAN和变分自编码器应用
        """
    )
    return


if __name__ == "__main__":
    app.run()
